home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GSCOLOR.C < prev    next >
C/C++ Source or Header  |  1993-05-17  |  11KB  |  377 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gscolor.c */
  20. /* Color and halftone operators for Ghostscript library */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gscspace.h"
  24. #include "gxcolor.h"
  25. #include "gxdevice.h"            /* for gx_color_index */
  26. #include "gxrefct.h"
  27. #include "gzstate.h"
  28. #include "gzcolor.h"
  29.  
  30. /* Define the standard color space types. */
  31. extern cs_proc_remap_color(gx_remap_DeviceGray);
  32. extern cs_proc_remap_color(gx_remap_DeviceRGB);
  33. extern cs_proc_remap_color(gx_remap_DeviceCMYK);
  34. const gs_color_space_type
  35.     gs_color_space_type_DeviceGray =
  36.      { gs_color_space_index_DeviceGray, 1,
  37.        gx_remap_DeviceGray, gx_no_install_cspace, gx_no_adjust_count
  38.      },
  39.     gs_color_space_type_DeviceRGB =
  40.      { gs_color_space_index_DeviceRGB, 3,
  41.        gx_remap_DeviceRGB, gx_no_install_cspace, gx_no_adjust_count
  42.      },
  43.     gs_color_space_type_DeviceCMYK =
  44.      { gs_color_space_index_DeviceCMYK, 4,
  45.        gx_remap_DeviceCMYK, gx_no_install_cspace, gx_no_adjust_count
  46.      };
  47.  
  48. /* Null color space installation procedure. */
  49. int
  50. gx_no_install_cspace(gs_color_space *pcs, gs_state *pgs)
  51. {    return 0;
  52. }
  53.  
  54. /* Null reference count adjustment procedure. */
  55. int
  56. gx_no_adjust_count(gs_color_space *pcs, gs_state *pgs, int delta)
  57. {    return 0;
  58. }
  59.  
  60. /* Force a parameter into the range [0.0..1.0]. */
  61. #define force_unit(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p)
  62. frac gx_color_unit_param(P1(floatp));
  63.  
  64. /* Forward declarations */
  65. private void load_transfer_map(P2(gs_state *, gx_transfer_map *));
  66.  
  67. /* setgray */
  68. int
  69. gs_setgray(gs_state *pgs, floatp gray)
  70. {    int code;
  71.     if ( pgs->in_cachedevice ) return_error(gs_error_undefined);
  72.     code = cs_adjust_count(pgs, -1);
  73.     if ( code < 0 ) return code;
  74.     pgs->ccolor->paint.values[0] = gray;
  75.     pgs->color_space->type = &gs_color_space_type_DeviceGray;
  76.     return gx_remap_color(pgs);
  77. }
  78.  
  79. /* currentgray */
  80. float
  81. gs_currentgray(const gs_state *pgs)
  82. {    gs_client_color *pcc = pgs->ccolor;
  83.     switch ( pgs->color_space->type->index )
  84.     {
  85.     case gs_color_space_index_DeviceGray:
  86.         return pcc->paint.values[0];
  87.     case gs_color_space_index_DeviceRGB:
  88.         return frac2float(color_rgb_to_gray(
  89.             float2frac(pcc->paint.values[0]),
  90.             float2frac(pcc->paint.values[1]),
  91.             float2frac(pcc->paint.values[2]),
  92.             pgs));
  93.     case gs_color_space_index_DeviceCMYK:
  94.         return frac2float(color_cmyk_to_gray(
  95.             float2frac(pcc->paint.values[0]),
  96.             float2frac(pcc->paint.values[1]),
  97.             float2frac(pcc->paint.values[2]),
  98.             float2frac(pcc->paint.values[3]),
  99.             pgs));
  100.     default:
  101.         return 0.0;
  102.     }
  103. }
  104.  
  105. /* sethsbcolor */
  106. int
  107. gs_sethsbcolor(gs_state *pgs, floatp h, floatp s, floatp b)
  108. {    float rgb[3];
  109.     color_hsb_to_rgb(force_unit(h), force_unit(s), force_unit(b), rgb);
  110.     return gs_setrgbcolor(pgs, rgb[0], rgb[1], rgb[2]);
  111. }
  112.  
  113. /* currenthsbcolor */
  114. int
  115. gs_currenthsbcolor(const gs_state *pgs, float pr3[3])
  116. {    float rgb[3];
  117.     gs_currentrgbcolor(pgs, rgb);
  118.     color_rgb_to_hsb(rgb[0], rgb[1], rgb[2], pr3);
  119.     return 0;
  120. }
  121.  
  122. /* setrgbcolor */
  123. int
  124. gs_setrgbcolor(gs_state *pgs, floatp r, floatp g, floatp b)
  125. {    int code;
  126.     gs_client_color *pcc = pgs->ccolor;
  127.     if ( pgs->in_cachedevice ) return_error(gs_error_undefined);
  128.     code = cs_adjust_count(pgs, -1);
  129.     if ( code < 0 ) return code;
  130.     pcc->paint.values[0] = r;
  131.     pcc->paint.values[1] = g;
  132.     pcc->paint.values[2] = b;
  133.     pgs->color_space->type = &gs_color_space_type_DeviceRGB;
  134.     return gx_remap_color(pgs);
  135. }
  136.  
  137. /* currentrgbcolor */
  138. int
  139. gs_currentrgbcolor(const gs_state *pgs, float pr3[3])
  140. {    gs_client_color *pcc = pgs->ccolor;
  141.     switch ( pgs->color_space->type->index )
  142.     {
  143.     case gs_color_space_index_DeviceGray:
  144.         pr3[0] = pr3[1] = pr3[2] = pcc->paint.values[0];
  145.         break;
  146.     case gs_color_space_index_DeviceRGB:
  147.         pr3[0] = pcc->paint.values[0];
  148.         pr3[1] = pcc->paint.values[1];
  149.         pr3[2] = pcc->paint.values[2];
  150.         break;
  151.     case gs_color_space_index_DeviceCMYK:
  152.     {    frac frgb[3];
  153.         color_cmyk_to_rgb(
  154.             float2frac(pcc->paint.values[0]),
  155.             float2frac(pcc->paint.values[1]),
  156.             float2frac(pcc->paint.values[2]),
  157.             float2frac(pcc->paint.values[3]),
  158.             pgs, frgb);
  159.         pr3[0] = frac2float(frgb[0]);
  160.         pr3[1] = frac2float(frgb[1]);
  161.         pr3[2] = frac2float(frgb[2]);
  162.     }    break;
  163.     default:
  164.         pr3[0] = pr3[1] = pr3[2] = 0.0;
  165.     }
  166.     return 0;
  167. }
  168.  
  169. /* setcmykcolor */
  170. int
  171. gs_setcmykcolor(gs_state *pgs, floatp c, floatp m, floatp y, floatp k)
  172. {    int code;
  173.     gs_client_color *pcc = pgs->ccolor;
  174.     if ( pgs->in_cachedevice ) return_error(gs_error_undefined);
  175.     code = cs_adjust_count(pgs, -1);
  176.     if ( code < 0 ) return code;
  177.     pcc->paint.values[0] = c;
  178.     pcc->paint.values[1] = m;
  179.     pcc->paint.values[2] = y;
  180.     pcc->paint.values[3] = k;
  181.     pgs->color_space->type = &gs_color_space_type_DeviceCMYK;
  182.     return gx_remap_color(pgs);
  183. }
  184.  
  185. /* currentcmykcolor */
  186. int
  187. gs_currentcmykcolor(const gs_state *pgs, float pr4[4])
  188. {    gs_client_color *pcc = pgs->ccolor;
  189.     switch ( pgs->color_space->type->index )
  190.     {
  191.     case gs_color_space_index_DeviceGray:
  192.         pr4[0] = pr4[1] = pr4[2] = 0.0;
  193.         pr4[3] = 1.0 - pcc->paint.values[0];
  194.         break;
  195.     case gs_color_space_index_DeviceRGB:
  196.     {    frac fcmyk[4];
  197.         color_rgb_to_cmyk(
  198.             float2frac(pcc->paint.values[0]),
  199.             float2frac(pcc->paint.values[1]),
  200.             float2frac(pcc->paint.values[2]),
  201.             pgs, fcmyk);
  202.         pr4[0] = frac2float(fcmyk[0]);
  203.         pr4[1] = frac2float(fcmyk[1]);
  204.         pr4[2] = frac2float(fcmyk[2]);
  205.         pr4[3] = frac2float(fcmyk[3]);
  206.     }    break;
  207.     case gs_color_space_index_DeviceCMYK:
  208.         pr4[0] = pcc->paint.values[0];
  209.         pr4[1] = pcc->paint.values[1];
  210.         pr4[2] = pcc->paint.values[2];
  211.         pr4[3] = pcc->paint.values[3];
  212.         break;
  213.     default:
  214.         pr4[0] = pr4[1] = pr4[2] = 0.0;
  215.         pr4[3] = 1.0;
  216.     }
  217.     return 0;
  218. }
  219.  
  220. /* setblackgeneration */
  221. int
  222. gs_setblackgeneration(gs_state *pgs, gs_mapping_proc proc)
  223. {    /****** INCOMPLETE ******/
  224.     pgs->black_generation = proc;
  225.     return 0;
  226. }
  227.  
  228. /* currentblackgeneration */
  229. gs_mapping_proc
  230. gs_currentblackgeneration(const gs_state *pgs)
  231. {    return pgs->black_generation;
  232. }
  233.  
  234. /* setundercolorremoval */
  235. int
  236. gs_setundercolorremoval(gs_state *pgs, gs_mapping_proc proc)
  237. {    /****** INCOMPLETE ******/
  238.     pgs->undercolor_removal = proc;
  239.     return 0;
  240. }
  241.  
  242. /* currentundercolorremoval */
  243. gs_mapping_proc
  244. gs_currentundercolorremoval(const gs_state *pgs)
  245. {    return pgs->undercolor_removal;
  246. }
  247.  
  248. /* settransfer */
  249. /* Remap=0 is used by the interpreter. */
  250. int
  251. gs_settransfer_remap(gs_state *pgs, gs_mapping_proc tproc, int remap)
  252. {    gx_transfer *ptran = &pgs->transfer;
  253.     /* We can safely decrement the reference counts */
  254.     /* of the non-gray transfer maps, because */
  255.     /* if any of them get freed, the rc_unshare can't fail. */
  256.     rc_decrement(ptran->red, pgs->memory_procs, "gs_settransfer");
  257.     rc_decrement(ptran->green, pgs->memory_procs, "gs_settransfer");
  258.     rc_decrement(ptran->blue, pgs->memory_procs, "gs_settransfer");
  259.     rc_unshare(ptran->gray, gx_transfer_map, pgs->memory_procs,
  260.            goto fail, "gs_settransfer");
  261.     ptran->gray->proc = tproc;
  262.     ptran->red = ptran->gray;
  263.     ptran->green = ptran->gray;
  264.     ptran->blue = ptran->gray;
  265.     ptran->gray->rc.ref_count += 3;
  266.     if ( remap )
  267.     {    load_transfer_map(pgs, ptran->gray);
  268.         return gx_remap_color(pgs);
  269.     }
  270.     else
  271.         return 0;
  272. fail:    rc_increment(ptran->red);
  273.     rc_increment(ptran->green);
  274.     rc_increment(ptran->blue);
  275.     return gs_error_VMerror;
  276. }
  277. int
  278. gs_settransf